/**
 * Copyright 2011 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.solarchallenge.client.gwtui.admin.edituseraccountdetails;

import com.google.common.collect.ImmutableMap;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.solarchallenge.client.event.EventCategory;
import com.google.solarchallenge.client.event.HistoryHandler;
import com.google.solarchallenge.client.gwtui.mvpinterfaces.Presenter;
import com.google.solarchallenge.client.rpc.ServiceProvider;
import com.google.solarchallenge.shared.dtos.UserAccountDto;

import java.util.ArrayList;
import java.util.Map;

/**
 * Presenter for Editing UserAccountDetails.
 *
 * @author Arjun Satyapal
 */
public class EditUserAccountDetailsPresenter extends Presenter {
  private EditUserAccountDetailsView display;
  private Map<Integer, UserAccountDto> map;

  public EditUserAccountDetailsPresenter(EditUserAccountDetailsView display,
      String historyToken) {
    super(display.getSolarChallengeHeaderPanel(), historyToken);
    this.display = display;
  }

  @Override
  public void go(HasWidgets container) {
    container.clear();
    container.add(display.asWidget());
    bind();
  }

  @Override
  public void bind() {
    display.getUserAccountDetailsWidget().getCheckBoxIsLoginAllowed()
        .setVisible(true);
    display.getButtonCancel().setVisible(false);
    display.getUserAccountDetailsWidget().setEnabled(false);
    display.getButtonCancel().addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        // TODO : On pressing cancel, reload with currently highlighted
        // approver instead of default.
        HistoryHandler.handleNewToken(EventCategory.EDIT_USER_ACCOUNT_DETAILS
            .getToken());
      }
    });

    display.getButtonBack().addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        HistoryHandler.handleNewToken(EventCategory.ADMIN_UI.getToken());
      }
    });

    display.getButtonEditSave().addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        if (display.getButtonCancel().isVisible()) {
          // This means user has clicked on save.
          int selectedIndex = display.getListBoxApproverList()
              .getSelectedIndex();
          UserAccountDto selectedDto = map.get(selectedIndex);
          UserAccountDto updatedDto = display.getUserAccountDetailsWidget()
              .getValuesAsDto();
          updatedDto.setKey(selectedDto.getKey());

          ServiceProvider.getServiceProvider().getApproverService()
              .updateUserAccountDto(updatedDto, getCallbackforUpdateApprover());
        } else {
          display.getUserAccountDetailsWidget().setEnabled(true);
          display.getButtonCancel().setVisible(true);
          display.getButtonEditSave().setText("Save");
          display.getUserAccountDetailsWidget().refreshLoginCategory();
        }
      }

      private AsyncCallback<Void> getCallbackforUpdateApprover() {
        display.setEnabled(false);
        AsyncCallback<Void> callback = new AsyncCallback<Void>() {
          @Override
          public void onSuccess(Void result) {
            Window.alert("Successfully updated the Approver details.");
            HistoryHandler
                .handleNewToken(EventCategory.EDIT_USER_ACCOUNT_DETAILS
                    .getToken());
          }

          @Override
          public void onFailure(Throwable caught) {
            display.setEnabled(true);
            Window.alert("Failed to save updated information. Try again.");
          }
        };
        return callback;
      }
    });

    display.getListBoxApproverList().addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        int selectedIndex = display.getListBoxApproverList().getSelectedIndex();
        if (selectedIndex < 0) {
          return;
        }
        updateApproverDetailWidget(selectedIndex);
      }
    });

    ServiceProvider.getServiceProvider().getApproverService()
        .getAllUserAccountDtos(getAllApproverCallback());
  }

  private AsyncCallback<ArrayList<UserAccountDto>> getAllApproverCallback() {
    AsyncCallback<ArrayList<UserAccountDto>> callback
        = new AsyncCallback<ArrayList<UserAccountDto>>() {
      @Override
      public void onFailure(Throwable caught) {
        // TODO(arjuns) : do proper handling.
        caught.printStackTrace();
        Window.alert("Failed to fetch list from server.");
      }

      @Override
      public void onSuccess(ArrayList<UserAccountDto> result) {
        if (result.size() == 0) {
          if (map != null) {
            map.clear();
          }
          return;
        }

        ImmutableMap.Builder<Integer, UserAccountDto> mapBuilder
            = new ImmutableMap.Builder<Integer, UserAccountDto>();
        int index = 0;
        for (UserAccountDto currSummaryDto : result) {
          display.getListBoxApproverList().addItem(currSummaryDto.getEmail());
          mapBuilder.put(index++, currSummaryDto);
        }

        // TODO : Fix this and see how index passed as part of token
        // can be selected by default.
        map = mapBuilder.build();
        display.getListBoxApproverList().setSelectedIndex(0);
        updateApproverDetailWidget(0);
      }
    };
    return callback;
  }

  private void updateApproverDetailWidget(int selectedIndex) {
    UserAccountDto dto = map.get(selectedIndex);
    display.getUserAccountDetailsWidget().updateValuesFromDto(dto);
    display.getUserAccountDetailsWidget().selectLoginCategory(
        dto.getLoginCategory());
  }
}
